﻿using System;
using System.Configuration;
using System.Data;

namespace Flagwind.Data
{
	internal class Logger
	{
		#region 常量定义

//		private const string PARAMETER_ENABLED = "enabled";
//		private const string PARAMETER_FILEPATH = "filePath";
//		private const string PARAMETER_EXECUTED_TIME = "executedTime";

		#endregion

		#region 静态字段

//		private static ParameterElementCollection _parameters;

		#endregion

		#region 静态属性

//		internal static ParameterElementCollection Parameters
//		{
//			get
//			{
//				if(_parameters == null)
//				{
//					_parameters = GetParameters();
//				}
//
//				return _parameters;
//			}
//		}

		#endregion

		#region 备份代码

		//日志相关
//		private static string _dataLogFile;

		/// <summary>
		/// 获取或者设置日志文件的路径，可以带Web相对路径
		/// </summary>
//		public static string DataLogFile
//		{
//			get
//			{
//				if(string.IsNullOrEmpty(_dataLogFile))
//				{
//					_dataLogFile = Logger.Parameters[PARAMETER_FILEPATH].Value;
//
//					if(!string.IsNullOrEmpty(_dataLogFile))
//					{
//						_dataLogFile = Utility.ReplaceWebRootPath(_dataLogFile);
//
//						string temp = Logger.Parameters[PARAMETER_ENABLED].Value;
//
//						if(temp != null)
//						{
//							_saveCommandLog = temp.ToUpper() == "TRUE";
//						}
//					}
//				}
//				return _dataLogFile;
//			}
//			set
//			{
//				_dataLogFile = value;
//			}
//		}

//		private static bool _saveCommandLog;

		/// <summary>
		/// 是否记录日志文件
		/// </summary>
//		public static bool SaveCommandLog
//		{
//			get
//			{
//
//				//string temp = DataLogFile; //必须先调用下，以计算_saveCommandLog
//				return _saveCommandLog;
//			}
//			set
//			{
//				_saveCommandLog = value;
//			}
//		}

		private static long _logExecutedTime = -1;

		/// <summary>
		/// 需要记录的时间，只有该值等于0会记录所有查询，否则只记录大于该时间的查询。单位毫秒。
		/// </summary>
		public static long LogExecutedTime
		{
			get
			{
				if(_logExecutedTime == -1)
				{
//					string temp = Logger.Parameters[PARAMETER_EXECUTED_TIME].Value;
//
//					if(string.IsNullOrEmpty(temp))
//					{
//						_logExecutedTime = 0;
//					}
//					else
//					{
//						long.TryParse(temp, out _logExecutedTime);
//					}

					_logExecutedTime = DataAccessSettings.Default.ExecuteTime;

				}
			

				return _logExecutedTime;
			}
			set
			{
				_logExecutedTime = value;
			}
		}

		private static Logger _default;
		private static object lockObj = new object();
		private System.Diagnostics.Stopwatch watch = null;

		/// <summary>
		/// 获取单例对象
		/// </summary>
		public static Logger Default
		{
			get
			{
				if(_default == null)
				{
					lock(lockObj)
					{
						if(_default == null)
						{
							_default = new Logger();
						}
					}
				}
				return _default;
			}
		}

		/// <summary>
		/// 默认构造函数
		/// </summary>
		public Logger()
		{
		}

		/// <summary>
		/// 是否开启执行时间记录
		/// </summary>
		/// <param name="startStopwatch"></param>
		public Logger(bool startStopwatch)
		{
			if(startStopwatch)
			{
				watch = new System.Diagnostics.Stopwatch();
				watch.Start();
			}
		}

		/// <summary>
		/// 重新开始记录执行时间
		/// </summary>
		public void ReSet()
		{
			if(watch != null)
			{
				watch.Reset();
			}
		}

		/// <summary>
		/// 获取当前执行的实际SQL语句
		/// </summary>
		public string CommandText
		{
			private set;
			get;
		}

		/// <summary>
		/// 写命令日志和执行时间（如果开启的话）
		/// </summary>
		/// <param name="command">命令对象</param>
		/// <param name="who">调用命令的源名称</param>
		/// <param name="elapsedMilliseconds">执行时间</param>
		public void Log(IDbCommand command, string who, out long elapsedMilliseconds)
		{
			CommandText = command.CommandText;
			elapsedMilliseconds = 0;
			if(DataAccessSettings.Default.EnableLog)
			{
				if(watch != null)
				{
					elapsedMilliseconds = watch.ElapsedMilliseconds;
					if((LogExecutedTime > 0 && elapsedMilliseconds > LogExecutedTime) || LogExecutedTime == 0)
					{
						RecordCommandLog(command, who);
						Log("Execueted Time(ms):" + elapsedMilliseconds + "\r\n", who);
					}
				}
				else
				{
					RecordCommandLog(command, who);
				}
			}
		}

		/// <summary>
		///写入日志消息
		/// </summary>
		/// <param name="msg">消息</param>
		/// <param name="who">发送者</param>
		public void Log(string msg, string who)
		{
			if(DataAccessSettings.Default.EnableLog)
			{
				WriteLog("//" + DateTime.Now.ToString() + " @" + who + " ：" + msg + "\r\n");
			}
		}

		/// <summary>
		/// 写错误日志，将使用 DataLogFile 配置键的文件名写文件，不受SaveCommandLog 影响，除非 DataLogFile 未设置或为空。
		/// </summary>
		/// <param name="command">命令对象</param>
		/// <param name="errmsg">调用命令的源名称</param>
		public void Error(IDbCommand command, string errmsg)
		{
			errmsg += ":Error";
			RecordCommandLog(command, errmsg);
		}

		/// <summary>
		/// 记录命令信息
		/// </summary>
		/// <param name="command">命令对象</param>
		/// <param name="who">执行人</param>
		private void RecordCommandLog(IDbCommand command, string who)
		{
			string temp = "//" + DateTime.Now.ToString() + " @" + who + " 执行命令：\r\nSQL=\"" + command.CommandText + "\"\r\n//命令类型：" + command.CommandType.ToString();
			if(command.Transaction != null)
			{
				temp = temp.Replace("执行命令", "执行事务");
			}
			WriteLog(temp);
			if(command.Parameters.Count > 0)
			{
				WriteLog("//" + command.Parameters.Count + "个命令参数：");
				for(int i = 0; i < command.Parameters.Count; i++)
				{
					IDataParameter p = (IDataParameter)command.Parameters[i];
					WriteLog("Parameter[\"" + p.ParameterName + "\"]\t=\t\"" + Convert.ToString(p.Value) + "\"  \t\t\t//DbType=" + p.DbType.ToString());
				}
			}
		}

		/// <summary>
		/// 写入日志
		/// </summary>
		/// <param name="log"></param>
		private void WriteLog(string log)
		{
			Flagwind.Diagnostics.Logger.Debug(log);

//			using(FileStream fs = new FileStream(DataLogFile, FileMode.Append, FileAccess.Write, FileShare.Write, 1024, FileOptions.Asynchronous))
//			{
//				byte[] buffer = System.Text.Encoding.UTF8.GetBytes(log + "\r\n");
//
//				IAsyncResult writeResult = fs.BeginWrite(buffer, 0, buffer.Length, (asyncResult) =>
//				{
//					FileStream fStream = (FileStream)asyncResult.AsyncState;
//					fStream.EndWrite(asyncResult);
//				}, fs);
//
//				fs.Flush();
//			}
		}

		#endregion

		#region 私有方法

//		private static ParameterElementCollection GetParameters()
//		{
//			// 获取配置节点。
//			DataSection section = ConfigurationManager.GetSection(DataSection.SectionName) as DataSection;
//
//			// 配置节点未找到。
//			if(section == null)
//			{
//				throw new ConfigurationErrorsException(string.Format("未找到配置节点 '{0}'。", DataSection.SectionName));
//			}
//
//			if(section.Logger == null)
//			{
//				throw new ConfigurationErrorsException("未找到配置节点 'logger'。");
//			}
//
//			return section.Logger.Parameters;
//		}

		#endregion
	}
}